package com.kun.base.net

import android.os.Build
import android.webkit.CookieManager
import androidx.annotation.RequiresApi
import com.kun.base.util.LogUtils
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 *提供retrofit apiService管理
 * 缓存使用过的ApiService实例
 *  @author : Kun
 *  @date : 2021/4/13
 *  @time : 15:33
 */
class ApiManager {
    companion object {
        private val lruCache = LruCache(10)

        /**
         * 超时时间
         */
        private const val CONNECT_TIME_OUT_SECONDS = 45L
        private const val READ_TIME_OUT_SECONDS = 60L

        private val client = OkHttpClient.Builder()
            .connectTimeout(CONNECT_TIME_OUT_SECONDS, TimeUnit.SECONDS)
            .readTimeout(READ_TIME_OUT_SECONDS, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .cookieJar(object : CookieJar {
                @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
                override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {
                    val cookieManager = CookieManager.getInstance()
                    cookieManager.setAcceptCookie(true)
                    for (cookie in cookies) {
                        cookieManager.setCookie(url.toString(), cookie.toString())
                    }
                    cookieManager.flush()
                }

                override fun loadForRequest(url: HttpUrl): MutableList<Cookie> {
                    val cookieList: MutableList<Cookie> = ArrayList()
                    val cookieManager = CookieManager.getInstance()
                    cookieManager.getCookie(url.toString())?.let {
                        LogUtils.e("cookies: $it")
                        val cookies = it.split(";")
                        for (cookie in cookies) {
                            cookieList.add(Cookie.parse(url, cookie)!!)
                        }
                    }
                    return cookieList
                }

            })
            .addInterceptor(ParamsInterceptor())
            .addInterceptor(LoggingInterceptor())
            .build();

        /**
         * 获取ApiService
         */
        fun <T> getServiceWithBaseUrl(service: Class<T>, baseUrl: String): T {
            val key = service.name + baseUrl

            return if (lruCache.contains(key)) {
                lruCache.get(key) as T
            } else {
                val o = createServiceWithBaseUrl(service, baseUrl)
                lruCache.put(key, o!!)
                o;
            }
        }

        /**
         * 创建ApiService实例
         *
         * @param service Service类型
         * @param baseUrl baseUrl
         * @param <T>
         * @return
         */
        private fun <T> createServiceWithBaseUrl(service: Class<T>, baseUrl: String): T {
            return Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build()
                .create(service)
        }
    }
}